package com.optimatch.model.db;

import java.util.ArrayList;

public class Dico {

	public static int MAX_SUGGESTIONS = 3;

	private DB db;

	private Node rootNode;
	private Node currentNode;

	public DB getDb() {
		return db;
	}

	private boolean nullNode = false;

	private int found = 0;

	public Dico(Node rootNode, DB db) {
		this.rootNode = rootNode;
		this.currentNode = rootNode;
		this.db = db;
	}

	public Dico() {
		this(new Node(),new DB());
	}

	public Dico(Dico d, DB db) {
		this(d.rootNode.clone(),db);
	}

	public Dico(DB db) {
		this();
		this.db = db;
		importerDico(db);
	}

	private void importerDico(DB db) {
		db.ajouterAuDico(this);
	}

	public String[] getNFirst() {
		String[] firstN;
		if (nullNode) {
			firstN = new String[0];
		} else {
			ArrayList<String> list = getNFirstArray();
			found = 0;
			firstN = new String[list.size()];
			int i = 0;
			for (String s : list) {
				firstN[i] = s;
				i++;
			}
		}
		return firstN;
	}

	private ArrayList<String> getNFirstArray() {
		ArrayList<String> array = getNFirstArray(currentNode);
		if (array.size() == MAX_SUGGESTIONS + 1) {
			array.remove(array.size() - 1);
			array.add("...");
		}
		return array;
	}

	private ArrayList<String> getNFirstArray(Node node) {
		ArrayList<String> array = new ArrayList<String>();
		ArrayList<Node> children = node.getChildren();
		int numChildren = children.size();
		if (node.isWord() && found < MAX_SUGGESTIONS + 1) {
			array.add(node.getWord());
			found++;
		}
		if (children != null && children.size() != 0) {
			Node child;
			int index = 0;
			while (found < MAX_SUGGESTIONS + 1 && index < numChildren) {
				child = children.get(index);
				array.addAll(getNFirstArray(child));
				index++;
			}
		}
		return array;
	}

	public void goBack() {
		Node previousNode = currentNode.getParent();
		if (previousNode != null) {
			currentNode = previousNode;
			nullNode = false;
		}
	}

	public void navigate(char c) {
		Node nextNode = currentNode.getSimilarChild(c);
		if (nextNode == null) {
			nullNode = true;
		} else {
			currentNode = nextNode;
		}
	}

	public void ajouterMot(String mot) {
		Node parent = rootNode;
		Node enfant;
		for(int i = 0; i<mot.length(); i++) {
			char c = mot.charAt(i);
			Node p = parent.getSimilarChild(c);
			if(p == null) {
				enfant = new Node(c);
				parent.addChild(enfant);
			}
			else {
				enfant = p;
			}
			parent = enfant;
		}
		parent.setWord(true);
	}

	public boolean goTo(String word) {
		currentNode = rootNode;
		nullNode = false;
		int size = word.length();
		for (int i = 0 ; i < size ; i++) {
			if (nullNode) {
				return false;
			} else {
				navigate(word.charAt(i));
			}
		}
		return !nullNode;
	}

	public String currentWord() {
		return currentNode.getWord();
	}

	public boolean isWord(String word) {
		return isWord(word,rootNode);
	}

	public boolean isWord(String word, Node currentNode) {
		if (word.length() == 0) {
			return currentNode.isWord();
		} else {
			Node nextNode = currentNode.getSimilarChild(word.charAt(0));
			if (nextNode == null) {
				return false;
			} else {
				return isWord(word.substring(1),nextNode);
			}
		}
	}

}
